﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using Abp.AspNetZeroCore.Net;
using Abp.Auditing;
using Abp.Authorization;
using ARchGL.Platform.Authorization;
using ARchGL.Platform.Dto;
using ARchGL.Platform.IO;
using ARchGL.Platform.Logging.Dto;
using ARchGL.Platform.Storage;

namespace ARchGL.Platform.Logging
{
    [AbpAuthorize(AppPermissions.Pages_Administration_Host_Maintenance)]
    public class WebLogAppService : PlatformAppServiceBase, IWebLogAppService
    {
        private readonly IAppFolders _appFolders;
        private readonly ITempFileCacheManager _tempFileCacheManager;

        public WebLogAppService(IAppFolders appFolders, ITempFileCacheManager tempFileCacheManager)
        {
            _appFolders = appFolders;
            _tempFileCacheManager = tempFileCacheManager;
        }

        /// <summary>
        /// 获取最后日志
        /// </summary>
        /// <returns></returns>
        [DisableAuditing]
        public GetLatestWebLogsOutput GetLatestWebLogs(string filter)
        {
            var lastLineTime = GetDateTime(filter);

            var directory = new DirectoryInfo(_appFolders.WebLogsFolder);
            if (!directory.Exists)
            {
                return new GetLatestWebLogsOutput { LatestWebLogLines = new List<string>() };
            }

            var lastLogFile = directory.GetFiles("*.txt", SearchOption.AllDirectories)
                                        .OrderByDescending(f => f.LastWriteTime)
                                        .FirstOrDefault();

            if (lastLogFile == null)
            {
                return new GetLatestWebLogsOutput();
            }

            var lines = AppFileHelper.ReadLines(lastLogFile.FullName).Reverse().Take(1000).ToList();
            var count = lines.Count();
            var logLineCount = 0;
            var lineCount = 0;

            for (int i = 0; i < count; i++)
            {
                var line = lines[i];

                var currentLineDate = GetDateTime(line);
                if (currentLineDate != DateTime.MinValue &&
                    lastLineTime != DateTime.MinValue &&
                    lastLineTime > currentLineDate)
                {
                    lines.RemoveAt(i);
                }

                if (line.StartsWith("DEBUG") ||
                    line.StartsWith("INFO") ||
                    line.StartsWith("WARN") ||
                    line.StartsWith("ERROR") ||
                    line.StartsWith("FATAL"))
                {
                    logLineCount++;
                }

                lineCount++;

                if (logLineCount == 100)
                {
                    break;
                }
            }

            //foreach (var line in count)
            //{
            //    var currentLineDate = GetDateTime(line);
            //    if (currentLineDate != DateTime.MinValue &&
            //        lastLineTime != DateTime.MinValue &&
            //        lastLineTime > currentLineDate)
            //        lines.re

            //    if (line.StartsWith("DEBUG") ||
            //        line.StartsWith("INFO") ||
            //        line.StartsWith("WARN") ||
            //        line.StartsWith("ERROR") ||
            //        line.StartsWith("FATAL"))
            //    {
            //        logLineCount++;
            //    }

            //    lineCount++;

            //    if (logLineCount == 100)
            //    {
            //        break;
            //    }
            //}

            return new GetLatestWebLogsOutput
            {
                LatestWebLogLines = lines.Take(lineCount).Reverse().ToList()
            };
        }

        /// <summary>
        /// 打包下载日志
        /// </summary>
        /// <returns></returns>
        public FileDto DownloadWebLogs()
        {
            //Create temporary copy of logs
            var logFiles = GetAllLogFiles();

            //Create the zip file
            var zipFileDto = new FileDto("WebSiteLogs.zip", MimeTypeNames.ApplicationZip);

            using (var outputZipFileStream = new MemoryStream())
            {
                using (var zipStream = new ZipArchive(outputZipFileStream, ZipArchiveMode.Create))
                {
                    foreach (var logFile in logFiles)
                    {
                        var entry = zipStream.CreateEntry(logFile.Name);
                        using (var entryStream = entry.Open())
                        {
                            using (var fs = new FileStream(logFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 0x1000, FileOptions.SequentialScan))
                            {
                                fs.CopyTo(entryStream);
                                entryStream.Flush();
                            }
                        }
                    }
                }

                _tempFileCacheManager.SetFile(zipFileDto.FileToken, outputZipFileStream.ToArray());
            }

            return zipFileDto;
        }

        private List<FileInfo> GetAllLogFiles()
        {
            var directory = new DirectoryInfo(_appFolders.WebLogsFolder);
            return directory.GetFiles("*.*", SearchOption.TopDirectoryOnly).ToList();
        }

        private DateTime GetDateTime(string str)
        {
            if (string.IsNullOrWhiteSpace(str) || str.Length < 29) return DateTime.MinValue;

            var date = str.Substring(6, 23).Replace(",", ".");
            DateTime.TryParse(date, out DateTime val);
            return val;
        }
    }
}